
#include "heaviside_tiling.h"
#include "register/op_def_registry.h"
#include "tiling/platform/platform_ascendc.h"
// #define BLOCK_SIZE 32
// #define BUFFER_NUM 1
// #define INOUTNUM 3
// namespace optiling {
// static ge::graphStatus TilingFunc(gert::TilingContext* context)
// {
//   HeavisideTilingData tiling;
//   uint64_t ub_size;
//   auto ascendcPlatform = platform_ascendc::PlatformAscendC(context->GetPlatformInfo());
//   ascendcPlatform.GetCoreMemSize(platform_ascendc::CoreMemType::UB, ub_size);
//   ub_size -= 8 * 1024;  //为Select预留的空间

//   int16_t aivNum = 1;

//   uint64_t typeSize = GetSizeByDataType(context->GetInputDesc(0)->GetDataType());
//   int32_t blockElem = BLOCK_SIZE / typeSize;
//   int32_t totalLength = context->GetInputTensor(0)->GetShapeSize();
//   int32_t totalLengthAligned = (totalLength+blockElem-1) / blockElem * blockElem;

//   uint32_t totalBlocks = totalLengthAligned / blockElem;
//   uint32_t coreDataNum;

//   coreDataNum = totalBlocks / aivNum;
//   uint32_t tail = totalBlocks %aivNum;
//   uint32_t iter = ub_size/INOUTNUM/BUFFER_NUM/BLOCK_SIZE;

//   tiling.set_iter(iter);
//   tiling.set_coreDataNum(coreDataNum);
//   tiling.set_tail(tail);
//   context->SetBlockDim(aivNum);
//   tiling.SaveToBuffer(context->GetRawTilingData()->GetData(), context->GetRawTilingData()->GetCapacity());
//   context->GetRawTilingData()->SetDataSize(tiling.GetDataSize());

//   return ge::GRAPH_SUCCESS;
// }
// }
namespace optiling {
    static ge::graphStatus TilingFunc(gert::TilingContext* context)
    {
      const static int BLOCK_SIZE = 32;
      const static int INOUT = 4;
      static int BUFFER_NUM = 1;
      HeavisideTilingData tiling;
      uint64_t ub_size;
      auto ascendcPlatform = platform_ascendc::PlatformAscendC(context->GetPlatformInfo());
      ascendcPlatform.GetCoreMemSize(platform_ascendc::CoreMemType::UB, ub_size);
      ub_size -= 8 * 1024;  

      int16_t coreNum = ascendcPlatform.GetCoreNumAiv();
      uint64_t typeSize = GetSizeByDataType(context->GetInputDesc(0)->GetDataType());
      int32_t blockElem = BLOCK_SIZE / typeSize;
      int32_t totalLength = context->GetInputTensor(0)->GetShapeSize();
      int32_t totalLengthAligned = (totalLength+blockElem-1) / blockElem * blockElem;
    
      uint32_t totalBlocks = totalLengthAligned / blockElem;
      uint32_t coreDataNum;
      coreNum = 25;
      coreDataNum = totalBlocks / coreNum;

      uint8_t tail = totalBlocks %coreNum;
      uint32_t iter = ub_size/INOUT/BUFFER_NUM/BLOCK_SIZE;
      
      tiling.set_iter(iter);
      tiling.set_coreDataNum(coreDataNum);
      tiling.set_tail(tail);
      context->SetBlockDim(coreNum);
      tiling.SaveToBuffer(context->GetRawTilingData()->GetData(), context->GetRawTilingData()->GetCapacity());
      context->GetRawTilingData()->SetDataSize(tiling.GetDataSize());
    
      return ge::GRAPH_SUCCESS;
    }
}

namespace ge {
static ge::graphStatus InferShape(gert::InferShapeContext* context)
{
    const gert::Shape* x1_shape = context->GetInputShape(0);
    gert::Shape* y_shape = context->GetOutputShape(0);
    *y_shape = *x1_shape;
    return GRAPH_SUCCESS;
}
}


namespace ops {
class Heaviside : public OpDef {
public:
    explicit Heaviside(const char* name) : OpDef(name)
    {
        this->Input("input")
            .ParamType(REQUIRED)
            .DataType({ge::DT_FLOAT, ge::DT_FLOAT16})
            .Format({ge::FORMAT_ND, ge::FORMAT_ND})
            .UnknownShapeFormat({ge::FORMAT_ND, ge::FORMAT_ND});
        this->Input("values")
            .ParamType(REQUIRED)
            .DataType({ge::DT_FLOAT, ge::DT_FLOAT16})
            .Format({ge::FORMAT_ND, ge::FORMAT_ND})
            .UnknownShapeFormat({ge::FORMAT_ND, ge::FORMAT_ND});
        this->Output("out")
            .ParamType(REQUIRED)
            .DataType({ge::DT_FLOAT, ge::DT_FLOAT16})
            .Format({ge::FORMAT_ND, ge::FORMAT_ND})
            .UnknownShapeFormat({ge::FORMAT_ND, ge::FORMAT_ND});

        this->SetInferShape(ge::InferShape);

        this->AICore()
            .SetTiling(optiling::TilingFunc);
        this->AICore().AddConfig("ascend910b");

    }
};

OP_ADD(Heaviside);
}
